Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Base Class Rule #84

Merged
merged 11 commits into from Mar 12, 2019

Conversation

masamichiueta
Copy link
Contributor

This PR is a proposal of a new rule, UseBaseClass.

What is UseBaseClass rule?

UseBaseClass rule is a rule to check whether an UI element uses custom class which is set as base class in config.

For example, if we have some base classes of UILabel like PrimaryLabel and SecondaryLabel that should be applied to all labels through the project, this rule checks whether labels in storyboards and xibs are set to base classes.

Why is this rule required?

As I describe above, many apps commonly have their own base UI components. But we often forget to set the custom class to the base classes in storyboard or xib. And new members often overlook the base components.

This rule can prevent the problem and this is the reason why I developed this rule.

How does it work?

Set element_class and base_classes in config like

use_base_class_rule:
  - element_class: UILabel
    base_classes:
      - PrimaryLabel
      - SecondaryLabel 

This enables to check UILabel uses PrimaryLabel or SecondaryLabel. If UILabel does not use the base classes, Xcode shows warnings like below.

Screen Shot 2019-03-11 at 18 53 35

@kateinoigakukun kateinoigakukun self-requested a review March 11, 2019 11:57
Copy link
Collaborator

@kateinoigakukun kateinoigakukun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution 🎉
Looks almost OK to me. But this rule can't work for inherited class because IB doesn't know about Swift type information.
So please add that caution on rule description of README.

return views.flatMap { validate(for: $0.view, file: xib, fileNameWithoutExtension: xib.fileNameWithoutExtension) }
}

private func validate<T: InterfaceBuilderFile>(for view: ViewProtocol, file: T, fileNameWithoutExtension: String) -> [Violation] {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is fileNameWithoutExtension needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, it's not used anywhere😅 I can remove it!

case baseClasses = "base_classes"
}

public static let `default` = UseBaseClassConfig.init()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this default and private init is not used anywhere. Can you remove them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see👍 Thanks!


public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
elementClass = try container.decodeIfPresent(Optional<String>.self, forKey: .elementClass).flatMap { $0 } ?? ""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If elementClass is nil or not present, this should throw a decoding error.
But in the case of baseClasses, it's OK because empty array in YAML is expressed in the same way of nil

elementClass: # This is invalid. Shouldn't be nil
baseClasses: # It's OK. This means empty array

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix to throw an error!

@masamichiueta
Copy link
Contributor Author

masamichiueta commented Mar 11, 2019

@kateinoigakukun Thank you for your quick review!

this rule can't work for inherited class because IB doesn't know about Swift type information

[Q] What do you mean about inherited class?

@kateinoigakukun
Copy link
Collaborator

kateinoigakukun commented Mar 11, 2019

@masamichiueta Oh, I misunderstood 😅. I mean PrimaryLabel can be inherited.
Do you think that CustomizedPrimaryLabel should be invalid? If so, it's my misunderstanding and you don't need to change README

class PrimaryLabel: UILabel {
    ...
}

class CustomizedPrimaryLabel: PrimaryLabel {
    ... 
}

@masamichiueta
Copy link
Contributor Author

I understand! As you said, this rule does not work for inherited classes. A developer needs to add the inherited classes to base_classes in yml.

I add caution on rule description👍

@masamichiueta
Copy link
Contributor Author

Updated. Please review again🙏

Copy link
Collaborator

@kateinoigakukun kateinoigakukun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, LGTM!

@kateinoigakukun kateinoigakukun merged commit 316dea3 into IBDecodable:master Mar 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants